﻿using LibBinary.DataSource;
using LibBinary.FileData;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LibBinary.FileDeclaration.Binary
{
    public class StringDeclaration : IFileDeclaration
    {
        private ILengthProvider length;
        private Encoding encoding;

        //length provide the number of bytes, not char
        public StringDeclaration(ILengthProvider length, Encoding encoding)
        {
            this.length = length;
            this.encoding = encoding;
        }

        public AbstractFileData Read(BinaryFileSource src, AbstractFileData parentNode)
        {
            var ret = new StringData(parentNode);
            int len = length.GetLength(ret);
            byte[] buffer = new byte[len];
            for (int i = 0; i < buffer.Length; ++i)
            {
                buffer[i] = src.Read<byte>();
            }
            ret.Data = encoding.GetString(buffer);

            var indexOfNull = ret.Data.IndexOf('\0');
            if (indexOfNull != -1)
            {
                ret.Data = ret.Data.Substring(0, indexOfNull);
            }
            return ret;
        }

        public void Write(BinaryFileSource src, AbstractFileData data)
        {
            var cdata = data.As<StringData>();
            if (cdata == null)
            {
                throw new WritingFormatException("Wrong data type.");
            }
            int len = length.GetLength(data);
            byte[] buffer = new byte[len];
            encoding.GetBytes(cdata.Data, 0, cdata.Data.Length, buffer, 0);
            foreach (var b in buffer)
            {
                src.Write<byte>(b);
            }
        }
    }
}
